package com.tanhua.server.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.Question;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.UserLocation;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MessagesService messagesService;

    @DubboReference
    private UserLocationApi userLocationApi;

    /*今日佳人*/
    public TodayBest todayBest() {
        //获取当前用户ID
        Long userId = UserHolder.getUserId();
        //调用mongo的服务查询今日佳人的信息
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        //如果recommendUser为空，则设置默认值
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1l);
            recommendUser.setScore(99D);
        }
        //调用mysql的服务查询今日佳人的具体信息
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        //将recommendUser转换成todayBest
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        return vo;
    }

    /*推荐朋友*/
    public PageResult recommendation(RecommendUserDto dto) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //调用recommendUserApi分页查询数据列表
        PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(), dto.getPagesize(), userId);
        //获取分页中的RecommendUser数据列表
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
        //判断列表是否为空，为空则返回
        if (items == null || items.size() <= 0) {
            return pr;
        }
        //不为空则提取列表里的所有推荐用户的id，存入list集合
        List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
        //添加筛选条件
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());
        //批量查询推荐用户信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
        //循环推荐数据列表，构造vo
        List<TodayBest> list = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo user = map.get(item.getUserId());
            if (user != null) {
                TodayBest vo = TodayBest.init(user, item);
                list.add(vo);
            }
        }
        pr.setItems(list);
        return pr;
    }

    /*查看佳人信息*/
    public TodayBest findPersonalInfo(Long userId) {
        //根据用户id查询用户详细信息
        UserInfo userInfo = userInfoApi.findById(userId);
        //查询当前用户和佳人的推荐数据
        RecommendUser recommendUser = recommendUserApi.findByUserId(userId, UserHolder.getUserId());
        //构造返回值
        TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
        return todayBest;
    }

    /*查看陌生人问题*/
    public String strangerQuestions(Long userId) {
        //查询陌生人问题
        Question question = questionApi.findByUserId(userId);
        //如果用户为设置陌生人问题，则设置返回一个默认问题
        return question == null ? "你喜欢java吗？" : question.getTxt();
    }

    /*回复陌生人问题*/
    public void replyStrangerQuestions(Long userId, String reply) {
        //获取当前用户id
        Long currentUserId = UserHolder.getUserId();
        //查询当前用户的详细信息
        UserInfo userInfo = userInfoApi.findById(currentUserId);
        //构造消息数据
        Map map = new HashMap();
        map.put("userId", currentUserId);
        map.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
        map.put("nickname", userInfo.getNickname());
        map.put("strangerQuestion", strangerQuestions(userId));
        map.put("reply", reply);
        String message = JSON.toJSONString(map);
        //调用huanXinTemplate发送消息
        Boolean result = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
        //发送失败则抛出异常
        if (!result) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    /*探花-左滑右滑*/
    public List<TodayBest> queryCardsList() {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //查询推荐数据列表,排除喜欢和不喜欢，10条
        List<RecommendUser> list = recommendUserApi.selectByUserId(userId, 10);
        //判断数据列表是否为空
        if (CollUtil.isEmpty(list)) {
            //如果数据列表为空，则构造默认数据
            String[] ids = recommendUser.split(",");
            list = new ArrayList<>();
            for (String id : ids) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(id));
                recommendUser.setToUserId(userId);
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                list.add(recommendUser);
            }
        }
        //获取推荐数据的用户id
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        //查询推荐数据的用户的用户信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
        //构造vo并返回
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser user : list) {
            UserInfo userInfo = map.get(user.getUserId());
            TodayBest vo = TodayBest.init(userInfo, user);
            vos.add(vo);
        }
        return vos;
    }

    /*探花-喜欢*/
    public void love(Long likeUserId) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //保存喜欢数据
        Boolean isLike = true;
        Boolean result = userLikeApi.save(userId, likeUserId, isLike);
        //判断是否保存成功
        if (!result) {
            //保存失败则抛出异常
            throw new BusinessException(ErrorResult.error());
        }
        //写入redis
        //如果以前是不喜欢，则先在redis中删除不喜欢的数据
        String hashKey1 = Constants.USER_NOT_LIKE_KEY + userId;
        redisTemplate.opsForSet().remove(hashKey1, likeUserId);
        //写入喜欢的数据
        String hashKye2 = Constants.USER_LIKE_KEY + userId;
        redisTemplate.opsForSet().add(hashKye2, likeUserId);
        //判断是否双向喜欢
        String hashKey3 = Constants.USER_LIKE_KEY + likeUserId;
        Boolean member = redisTemplate.opsForSet().isMember(hashKey3, userId);
        if (member) {
            //如果双向喜欢，则添加好友
            messagesService.addContacts(likeUserId);
        }
    }

    /*探花-不喜欢*/
    public void unlove(Long likeUserId) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //保存喜欢数据
        Boolean isLike = false;
        Boolean result = userLikeApi.save(userId, likeUserId, isLike);
        //判断是否保存成功
        if (!result) {
            //保存失败则抛出异常
            throw new BusinessException(ErrorResult.error());
        }
        //在redis中写入不喜欢的数据
        String hashKye2 = Constants.USER_NOT_LIKE_KEY + userId;
        redisTemplate.opsForSet().add(hashKye2, likeUserId);
    }

    /*搜附近*/
    public List<NearUserVo> searchNearUser(String gender, String distance) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //查询附近用户(包括当前用户自己)
        List<Long> ids = userLocationApi.searchNearUser(userId, Double.valueOf(distance));
        //判断数据列表是否为空
        if (CollUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        //添加用户查询条件
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        //调用api查询这些用户的详细信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo);
        //构造vo
        List<NearUserVo> vos = new ArrayList<>();
        for (Long id : ids) {
            //排除当前用户
            if (id == userId) {
                continue;
            }
            UserInfo info = map.get(id);
            if (info != null) {
                NearUserVo vo = NearUserVo.init(info);
                vos.add(vo);
            }
        }
        return vos;
    }
}
